/*
    2017/6/14
    新增，可注入按钮，按钮功能可选，保存图片功能
*/ 
(function (global, factory){
    console.warn("该组件css基于bootstrap");
    if (typeof global.document == "undefined"){
        console.error("请在window下使用该插件");
    }else if (typeof global.$ == "undefined" ||
              typeof global.jQuery == "undefined"){
        console.error("该插件依赖jquery");
    }else{
        global.$Z = factory;
    }
}(window, function (option){
    var _ = this;
    // 容器
    var container = null;
    // 工具栏
    var util_span = null;
    // 工具载体对象
    var utillist = {};

    var close_func = null;
    // 选中的画板
    this.active_img = null;
    // 笔的大小
    var pansize = 3;
    // 笔的颜色
    var pancolor = "red";
    // 是否可以移动
    var canmove = false;
    // 是否在使用橡皮擦
    var isclean = false;
    // 是否在画画
    var drawState = false;

    var doubleTap = false;
    // 是否在裁剪状态
    var isClip = false;

    var img_list = [];

    var leftList = null;

    var range = null;

    this.back_can = null;

    this.back_ctx = null;

    this.back_lastX = 0;
    this.back_lastY = 0;

    this._default_option = {
        // 默认装载的按钮
        btn_list: [
                'closeBtn',
                'changeScale',
                'rotateLeftBtn',
                'rotateRightBtn',
                'redoBtn',
                'smallPan',
                'middlePan',
                'bigPan',
                'redPan',
                'blackPan',
                'xiangpi',
                'moveBtn',
                'bottomBtn',
                'reloadBtn',
                'saveBtn',
                'clipBtn'
            ],
        // 用户自定义按钮
        // 按钮名称，
        custom_btn: {},
        beforeLoad: null,
        // 表面是否允许涂写
        backEditable: true
    };

    this.show = function (){
        container.show();
        if (this._default_option.backEditable) {
            _.back_can.attr('width', container.width())
            _.back_can.attr('height', container.height())
        }
        return this;
    };

    this.hide = function (){
        container.hide();
        return this;
    };

    this.append = function (obj){
        container.append(obj);
        return this;
    }
    this.appendUtil = function (obj){
        container.append(obj);
        return this;
    }

    function _init(obj){
        // 初始化容器
        if (obj){
            container = $(obj);
        } else {
            container = $("<div id='zyf-can'/>");
            container.css({
                'width': '100%',
                'height': '100%',
                'position': 'fixed',
                'top':'0',
                'right':'0',
                'textAlign': 'center',
                'background': 'white',
                'display': 'none',
                'overflow': 'hidden',
                'z-index': 1000
            });
        }
        if (typeof option != "undefined"){
            for (var i in option){
                _._default_option[i] = option[i];
            }
        }
        if (_._default_option.backEditable) {
            createEditableBackgroud();
        }
        $("body").append(container);
        $(document).on("mouseup", function (){
        	if (_.active_img){
        		_.active_img.event_up();
        	}
        })
        $(document).on("touchend", function (){
        	if (_.active_img){
        		_.active_img.event_up();
        	}
        })
        // 容器状态工具类
        _loadutil();
    };

    function createEditableBackgroud(){
        _.back_can = $("<canvas/>").appendTo(container);
        _.back_ctx = _.back_can.get(0).getContext('2d');
        $(_.back_can).attr('width', container.width());
        $(_.back_can).attr('height', container.height());
        backRegistDraw();
    }

    function backRegistDraw() {
        var _that = _;
        var ox;
        var oy;
        var ox2;
        var oy2;
        _.back_can.on("mousedown", function (e){
            // 重置range的值
            ox = e.offsetX
            oy = e.offsetY
            if (canmove === false){
                drawState = true;
                var x = e.clientX
                var y = e.clientY
                _that.back_lastX = x;
                _that.back_lastY = y;
                backDraw(x, y, false, isclean);
                return false;
            }
        });
        _.back_can.on("mousemove", function (e){
            if (drawState){
                if (canmove === false){
                    if (_that.back_lastX == null || _that.back_lastX == null ){
                        _that.back_lastX = e.clientX
                        _that.back_lastY = e.clientY
                    }
                    backDraw(e.clientX,e.clientY,true,isclean);
                }
                return false;
            }
        });

        _.back_can.on("touchstart", function (e){
            e = e.originalEvent.touches[0];
            ox2 = e.screenX
            oy2 = e.screenY
            if (canmove === false){
                drawState = true;
                var x = e.clientX
                var y = e.clientY
                _that.back_lastX = x;
                _that.back_lastY = y;
                backDraw(x, y, false, isclean);
                return false;
            }
        });
        _.back_can.on("touchmove", function (ev){
            e = ev.originalEvent.touches[0];
            if (drawState){
                if (!canmove){ 
                    if (_that.back_lastX == null || _that.back_lastY == null ){
                        _that.back_lastX = e.clientX
                        _that.back_lastY = e.clientY
                    }
                    backDraw(e.clientX,e.clientY,true,isclean);
                    return false;
                }
            }
            return false;
        });
    }

    function backDraw(x, y, isDown, isclean) {
        var ctx = _.back_ctx;
        if (isDown) {
            ctx.globalCompositeOperation = isclean ? "destination-out" : "source-over";
            ctx.beginPath();
            ctx.strokeStyle = pancolor;
            ctx.lineWidth = isclean ? 30 : pansize;
            ctx.lineJoin = "round";
            ctx.moveTo(_.back_lastX, _.back_lastY);
            if (_.back_lastX == x && _.back_lastY == y){
                x++;
                y++;
            }
            ctx.lineTo(x, y);
            ctx.closePath();
            ctx.stroke();
        }
        _.back_lastX = x;
        _.back_lastY = y;
    }

    function resetRange(){
        var act = _.active_img;
        var nw = $(act.oimg)[0].naturalWidth + $(act.oimg)[0].naturalHeight
        var w = act.width + act.height;
        var value = w / nw * 0.5 * 100;
        range.setVal(value);
        return value
    }
    // 销毁所有对象
    function _destruct(){
        var len = img_list.length;
        for(var i = len-1; i >= 0; i--){
            img_list[i]._destruct();
            img_list[i] = null;
        }
        img_list = [];
    }
    function resetBtn(){
        container.find(".tuodong").removeClass("active")
        container.find(".xiangpi").removeClass("active")
    }
    function _loadutil (){
        util_span = $("<span class='can-util form-inline' style='position:fixed;bottom:30px;left:0;z-index:55;'>");
        var btnlist = {};
        btnlist.closeBtn = $("<button class='btn btn-info glyphicon glyphicon-off'>关闭</button>")
            .click(function (){
                if (close_func){
                    close_func(_, img_list)
                }
                container.hide();
                _destruct();
                cleanimgdata();
            });
        btnlist.rotateLeftBtn = $("<button class='btn btn-info fa fa-rotate-left'>左旋</button>")
            .click(function (){
                _.active_img.rotateLeft();
            });
        btnlist.rotateRightBtn = $("<button class='btn btn-info fa fa-rotate-right'>右旋</button>")
            .click(function (){
                _.active_img.rotateRight();
            });
        btnlist.redoBtn = $("<button class='btn btn-info fa fa-reply'>撤销</button>")
            .click(function (){
                repealaction();
            });
        btnlist.smallPan = $("<button class='btn btn-info pan-size pan active'>小</button>")
            .click(function (){
                canmove = false;
                _.active_img.can_edit.css("cursor", "crosshair");
                resetBtn();
                $(".pan-size").removeClass("active");
                $(this).addClass("active");
                pansize = 3;
            });
        btnlist.middlePan = $("<button class='btn btn-info pan-size pan'>中</button>")
            .click(function (){
                canmove = false;
                _.active_img.can_edit.css("cursor", "crosshair");
                resetBtn();
                $(".pan-size").removeClass("active");
                $(this).addClass("active");
                pansize = 5;
            });
        btnlist.clipBtn = $("<button class='btn btn-info'>裁剪</button>").click(function (){
            _.active_img.setClip();
        });
        btnlist.saveBtn = $("<button class='btn btn-info'>保存</button>").click(function (){
            _.active_img.saveAsBase64();
        })
        btnlist.bigPan = $("<button class='btn btn-info pan-size pan'>大</button>")
            .click(function (){
                canmove = false;
                _.active_img.can_edit.css("cursor", "crosshair");
                resetBtn();
                $(".pan-size").removeClass("active");
                $(this).addClass("active");
                pansize = 10;
            });
        btnlist.redPan = $("<button style='color:red' class='btn btn-info pan pan-color active glyphicon glyphicon-pencil'></button>")
            .click(function (){
                canmove = false;
                _.active_img.can_edit.css("cursor", "crosshair");
                resetBtn();
                $(".pan-color").removeClass("active");
                $(this).addClass("active");
                pancolor = "red";
            });
        btnlist.scaleBigBtn = $("<button class='btn btn-info glyphicon glyphicon-zoom-in'>放大</button>")
            .click(function (){
                _.active_img.scale(1.25);
            });
        btnlist.scaleSmallBtn = $("<button class='btn btn-info glyphicon glyphicon-zoom-out'>缩小</button>")
            .click(function (){
                _.active_img.scale(0.8);
            });
        btnlist.blackPan = $("<button style='color:blue' class='btn btn-info pan pan-color glyphicon glyphicon-pencil'></button>")
            .click(function (){
                canmove = false;
                _.active_img.can_edit.css("cursor", "crosshair");
                resetBtn();
                $(".pan-color").removeClass("active");
                $(this).addClass("active");
                pancolor = "blue";
            });
        btnlist.reloadBtn = $("<button class='btn btn-info glyphicon glyphicon-refresh'>重置</button>")
            .click(function (){
                _.active_img.can_box.css("top", 0);
                // _.active_img.can_img.css("top", 0);
                // _.active_img.can_edit.css("top", 0);
                _.active_img._loadimg(_.active_img.oimg,2);
                _.active_img.rotatestate = 0;
            });
        btnlist.moveBtn = $("<button class='btn btn-info tuodong fa fa-arrows'>移动</button>")
            .click(function (){
                $(this).addClass("active");
                canmove = true;
                _.active_img.can_edit.css("cursor", "move");
                isclean = false;
                container.find(".xiangpi").removeClass("active");
            });
        btnlist.bottomBtn = $("<button class='btn btn-info fa fa-arrow-down'>置底</button>")
            .click(function (){
                _.active_img.can_box.css({"bottom": 0, "top": "auto"});
                console.log(($('body').width()-_.active_img.width)/2 + "px")
                _.active_img.can_box.css("left", ($('body').width()-_.active_img.width)/2 + "px")
                // _.active_img.can_img.css({"bottom": 0, "top": "auto"});
                // _.active_img.can_edit.css({"bottom": 0, "top": "auto"});
                // _.active_img.can_img.css("left", ($(document).width()-_.active_img.width)/2 + "px")
                // _.active_img.can_edit.css("left", ($(document).width()-_.active_img.width)/2 + "px")

            });
        btnlist.xiangpi = $("<button class='btn xiangpi btn-info fa fa-eraser'>橡皮</button>")
            .click(function (){
                $(this).addClass("active")
                isclean = true;
                canmove = false;
                container.find(".tuodong").removeClass("active");
                _.active_img.can_edit.css("cursor", "crosshair");
            });
        btnlist.changeScale = $("<div style='height:40px;width:250px;display: inline-block' />");

        btnlist.changeScale.appendTo($("body"))
        range = new rangeUtil({father_box: btnlist.changeScale,
            rangebox_css: {
                position: 'absolute',
                top:'40px',
                width: '20px',
                height: '20px',
                'border-radius': '50%',
                'background-color': '#646464',
                'box-shadow': '2px 2px 2px rgba(0,0,0,.2)'
            },
            defaultValue: 50,
            type:2})
            .registCallback(function (data){
                var point = data.point;
                _.active_img.changeScale(point / 50)
        }).registMovingCallback(function (data){
            var point = data.point;
            _.active_img.changeBoxScale(point / 50)
        })
        utillist.closeBtn = btnlist.closeBtn;
        // this.utillist.roteBtn = roteBtn;
        utillist.redoBtn = btnlist.redoBtn;
        utillist.scaleBigBtn = btnlist.scaleBigBtn;
        utillist.scaleSmallBtn = btnlist.scaleSmallBtn;
        for(var i=0;i<_._default_option.btn_list.length;i++){
            if (typeof _._default_option.custom_btn[_._default_option.btn_list[i]] != "undefined"){
                var custom_obj = _._default_option.custom_btn[_._default_option.btn_list[i]];
                (function (obj){
                    obj.btn.click(function (){
                        obj.func(_,img_list,$(this));
                    })
                })(custom_obj);
                util_span.append(custom_obj.btn)
            }else if (typeof btnlist[_._default_option.btn_list[i]] != "undefined"){
                util_span.append(btnlist[_._default_option.btn_list[i]])
            }
        }
        util_span.appendTo(container)
        container.find(".pan").click(function (){
            container.find('.tuodong').removeClass("active");
            canmove = false;
            _.active_img.can_edit.css("cursor", "crosshair");
            isclean = false;
        })
    }

    this.goNextImg = function()
    {
        for (var i=0;i<img_list.length;i++)
        {
            if (img_list[i] == this.active_img)
            {
                if (img_list[i+1])
                {
                    this.active_img = img_list[i+1]
                    img_list[i+1].showTop();
                }
                else
                {
                    this.active_img = img_list[0]
                    img_list[0].showTop();
                }
                break;
            }
        }
    }

    // 撤销
    function repealaction(){
        if (_.active_img.imgdatalist_edit.length > 0){
            var obj = _.active_img.imgdatalist_edit.pop()
            var data = obj.data;
            var data2 = _.active_img.imgdatalist_img.pop().data;
            _.active_img.width = data.width
            _.active_img.height = data.height
            _.active_img.rotatestate = obj.rotate;
            _.active_img.resizeWH(data.width, data.height);
            // _.active_img.showCenter();
            _.active_img.ctx_edit.clearRect(0,0,_.active_img.width,_.active_img.height);  
            _.active_img.ctx_edit.putImageData(data, 0, 0);
            _.active_img.ctx_img.clearRect(0,0,_.active_img.width,_.active_img.height);  
            _.active_img.ctx_img.putImageData(data2, 0, 0);
            if (_.active_img.imgdatalist_edit.length<=0){
                utillist.redoBtn.addClass("disabled");
            }
        }
    };

    // 创建右侧滑动篮
    function createList(){
        var div1 = $("<div>").css({width: 300, 
                    height: "100%",
                    position:"fixed",
                    top:0,right:"-300px",
                    "zIndex": 55,
                    border:"1px solid lightblue",
                    background: "white"
                });
        var div = $("<div>").css({height: "100%", "overflowY": "auto"})
        for (var i=0;i<img_list.length;i++){
            var src = $(img_list[i].oimg).attr("src");
            var img = $("<img>").attr("src", src)
                .css({width:"250px",
                      margin: "10px auto",
                      border: "1px solid #fff"
                  })
                .appendTo(div);
            (function (num, obj){
                obj.click(function (){
                    _.active_img = img_list[num]
                    // 重置range的值
                    resetRange();
                    img_list[num].showTop();
                })
            }(i,img));
        }
        var hander = $("<div class=''><i class='fa fa-chevron-left'></i></div>")
            .css({
                    "width": "20px",
                    "height": "50px",
                    "lineHeight": "50px",
                    "background": "white",
                    "border-top-left-radius": "10px",
                    "border-bottom-left-radius": "10px",
                    "position": "absolute",
                    "left": "-19px",
                    "bottom": "100px",
                    "border": "1px solid lightblue",
                    "border-right": "none"
                }).click(function (){
                    if ($(this).hasClass("open")){
                        $(this).removeClass("open").find("i")
                            .removeClass("fa-chevron-right")
                            .addClass("fa-chevron-left");
                            div1.stop(true,true).animate({"right": "-300px"}, 300)
                    } else {
                        $(this).addClass("open").find("i")
                            .addClass("fa-chevron-right")
                            .removeClass("fa-chevron-left");
                            div1.stop(true,true).animate({"right": "0"}, 300)
                    }
                });
        div1.append(div).append(hander).appendTo(container);
        leftList = div1;
    }

    function cleanimgdata(){
        for (var i=0; i<img_list.length; i++)
        {
            img_list[i].imgdatalist_img = [];
            img_list[i].imgdatalist_edit = [];
        }
        
    };

    function autoResize(){
        // 图片总数
        var num = img_list.length;
        var c_w = container.width();
        var c_h = container.height();
        // 计算出每个对象的坐标与大小，并记录
        // 得到需要循环的 x 和 y 的值, x 横坐标，y 纵坐标
        var sqrt = Math.sqrt(num);
        var x = Math.ceil(sqrt);
        var y = Math.round(sqrt);
        // 用for循环进行resize
        for (var i=0;i<num;i++){
            img_list[i].resizeTo(c_w / x, c_h / y, 1);
        }
        var ceil_x = Math.ceil(c_w / x);
        var ceil_y = Math.ceil(c_h / y);
        var key = 0
        outerloop:
        for (var i=0;i<y;i++){
            for (var j=0;j<x;j++){
                if (key >= num){
                    break outerloop;
                }
                img_list[key].removeTo(j * ceil_x + (ceil_x - img_list[key].width)/2, i * ceil_y + (ceil_y - img_list[key].height)/2);
                key++;
            }
        }
    };

    this.onclose = function (func){
        if (typeof func != "undefined" && func){
            close_func = func
        }
    }

    // 容器装载图像，每一个图像都是一个对象
    this.loadimg = function (img){
        _destruct();
        cleanimgdata();
        if (leftList != null){
            leftList.remove();
        }
        // 传入了数组
        if (img instanceof Array){
            for(var i=0; i<img.length; i++){
                if (typeof img[i].img == 'undefined')
                {   
                    var ins = new _instance(img[i]);
                }
                else
                {
                    var ins = new _instance(img[i].img, img[i].data);
                }
                img_list.push(ins);
            }
            this.active_img = img_list[0];
            this.active_img.showTop();
            // 右侧浏览模块
            createList();
            // 自动排版
            autoResize();
        }else{
            if (typeof img.img == 'undefined')
            {   
                var ins = new _instance(img);
            }
            else
            {
                var ins = new _instance(img.img, img.data);
            }
            this.active_img = ins;
            this.active_img.showTop();
            img_list.push(ins);
        }
        // 重置range的值
        setTimeout(function (){
            resetRange();
        }, 0);
        return this;
    }

    if (typeof f != 'undefined'){
        if (typeof f !== "object" && $(f).size() != 1){
            console.error("无效的传入对象！");
        } else {
            console.log("初始化容器类！")
            _init(f);
        };
    } else {
        _init();
    }

/************************************************/

    // 图像的容器类
    function _instance(img, data){
        var _that = this;
        this.can_img = null;
        this.can_edit = null;
        this.can_box = null;
        this.ctx_img = null;
        this.ctx_edit = null;
        this.width = 0;
        this.img = null;
        this.oimg = null;
        this.height = 0;
        this.lastX = null;
        this.lastY = null;
        this.max_history = 5;
        // 缓存的数据
        this.can_data = null;
        // 数据缓存列表
        this.imgdatalist_img = [];
        this.imgdatalist_edit = [];
        // 0：0度 1：90度 2:180度 3:270度
        this.rotatestate = 0;

        this.setClip = function (){
            isClip = true;
        }
        // 居中显示
        this.showCenter = function (){
            this.can_box.css("left", ($('body').width()-this.width)/2 + "px")
            this.can_box.css("top", ($('body').height()-this.height)/2 + "px")
            this.resizeWH(this.width, this.height);
            return this;
        };

        // 状态图像
        /*
            type : 0    载入图像canvas
            type : 1    载入编辑canvas
            type : 2    初始化图像
        */
        this._loadimg = function (img, type, size){
            // 居中显示
            img = $(img)[0]
            var width = img.naturalWidth
            var height = img.naturalHeight
            this.img = img;
            if (typeof size == "undefined"){
                this.oimg = img;
            }
            this.lastX = null;
            this.lastY = null;
            size = size ? size : 1;
            if (type == 1){
                this.width = Math.floor(width * size);
                this.height = Math.floor(height * size);
                this.can_box.css("width", this.width + 2);
                this.can_box.css("height",this.height +2 );
                this.can_edit.attr("width", this.width);
                this.can_edit.attr("height",this.height);
                // this.can_edit.css("left", ($(document).width()-this.width)/2 + "px")
                this.ctx_edit.clearRect(0,0,this.width,this.height);
                this.ctx_edit.drawImage(img, 0, 0, width, height, 0,0, this.width,this.height);
                this.can_edit.css({opacity: 1})
                this.can_img.css({opacity: 1})
            }else if (type == 0){
                // this.width = Math.floor(this.width * size);
                // this.height = Math.floor(this.height * size);
                this.can_box.css("width", this.width + 2);
                this.can_box.css("height",this.height +2 );
                this.can_img.attr("width", this.width);
                this.can_img.attr("height",this.height);
                // this.can_img.css("left", ($(document).width()-this.width)/2 + "px")
                this.ctx_img.drawImage(img, 0, 0, width, height, 0,0, this.width,this.height);
                this.can_edit.css({opacity: 1})
                this.can_img.css({opacity: 1})
            }else if (type == 2){
                // 拿到缩放后的size
                if ((width / height) > ($('body').width() / $('body').height())) {
                    size = $('body').width() / width;
                } else {
                    size = $('body').height() / height;
                }
                this.width = Math.floor(width * size);
                this.height = Math.floor(height * size);
                this.showCenter();
                this.ctx_img.drawImage(img, 0, 0, width, height, 0,0, this.width,this.height);
                this.ctx_edit.clearRect(0,0,this.width,this.height);
            }
            return this;
        };

        /**
         * img1编辑的图片
         * img2展示的图片
         */
        this._loadimg2 = function (img1, img2, width, height){
            this.width = width;
            this.height = height;
            this.lastX = null;
            this.lastY = null;
            var width1 = img1.naturalWidth
            var height1 = img1.naturalHeight
            var width2 = img2.naturalWidth
            var height2 = img2.naturalHeight
            this.can_box.css("width", this.width + 2);
            this.can_box.css("height",this.height +2 );
            this.can_edit.attr("width", this.width);
            this.can_edit.attr("height",this.height);
            this.can_img.attr("width", this.width);
            this.can_img.attr("height",this.height);
            // this.can_edit.css("left", ($(document).width()-this.width)/2 + "px")
            this.ctx_edit.clearRect(0,0,this.width,this.height);
            this.ctx_edit.drawImage(img1, 0, 0, width1, height1, 0,0, this.width,this.height);
            this.ctx_img.drawImage(img2, 0, 0, width2, height2, 0,0, this.width,this.height);
            this.can_edit.css({opacity: 1})
            this.can_img.css({opacity: 1})
        }

        this.showTop = function (){
            for (var i = 0; i < img_list.length; i++){
                var obj = img_list[i]
                obj.setIndex(1).can_box.removeClass('_can_active');
            }
            this.setIndex(10).can_box.addClass('_can_active');
        }

        this.setIndex = function (index){
            this.can_edit.css("zIndex", index);
            this.can_img.css("zIndex", index);
            this.can_box.css("zIndex", index);
            return this;
        }

        this.loadData = function (data){
            if (data)
            {
                this.can_data = data
            }
        }

        this.get = function (k){
            return this.can_data[k];
        }

        this.set = function (k, v){
            this.can_data[k] = v;
        }

        this.event_up = function (){
            if (isClip) {
                _that.stopClip();
                return;
            }
            drawState = false;
            _that.lastX = null;
            _that.lastY = null;
        }

        function registDraw(){
            var that = _that;
            var ox;
            var oy;
            var ox2;
            var oy2;
            // TODO 用发布订阅和工厂模式包装一下
            _that.can_edit.on("mousedown", function (e){
                _.active_img = that
                // 重置range的值
                var scale = resetRange();
                that.showTop();
                ox = e.offsetX
                oy = e.offsetY
                var x = e.clientX - that.can_box.offset().left;
                var y = e.clientY - that.can_box.offset().top + $(document).scrollTop();
                if (isClip) {
                    _that.clipStart(x, y);
                    return false;
                }
                if (isclean){
                    saveimgdata();
                }
                drawState = true
                if (canmove === false){
                    saveimgdata();
                    drawState = true;
                    // var x = e.clientX - that.can_edit.offset().left;
                    // var y = e.clientY - that.can_edit.offset().top + $(document).scrollTop();
                    that.lastX = x;
                    that.lastY = y;
                    draw(x, y, false, isclean);
                    return false;
                }
            });
            _that.can_edit.on("mousemove", function (e){
                // if (_.active_img == that || true){
                if (isClip && clip_start) {
                    that.clipMove(e.clientX - that.can_box.offset().left, 
                                    e.clientY - that.can_box.offset().top + $(document).scrollTop());
                    return false;
                }
                    if (drawState){
                        if (canmove){
                            if (_.active_img == that){
                                var nx = that.can_box.position().left
                                var nx = that.can_box[0].offsetLeft

                                var ny = that.can_box.position().top
                                var ny = that.can_box[0].offsetTop
                                // var nx = that.can_edit.position().left
                                // var nx = that.can_edit[0].offsetLeft

                                // var ny = that.can_edit.position().top
                                // var ny = that.can_edit[0].offsetTop
                                var left = e.offsetX - ox + nx;
                                var top = e.offsetY - oy + ny;
                                that.can_box.css({left:left+"px", top: top + "px"});
                                // that.can_edit.css({left:left+"px", top: top + "px"});
                                // that.can_img.css({left:left+"px", top: top + "px"});
                            }
                        }else{
                            if (_that.lastX == null || _that.lastY == null ){
                                _.active_img.lastX = _.active_img.lastY = null;
                                _that.lastX = e.clientX - that.can_box.offset().left;
                                _that.lastY = e.clientY - that.can_box.offset().top + $(document).scrollTop()
                                // _that.lastX = e.clientX - that.can_edit.offset().left;
                                // _that.lastY = e.clientY - that.can_edit.offset().top + $(document).scrollTop()
                            }
                            draw(e.clientX - that.can_box.offset().left, 
                                    e.clientY - that.can_box.offset().top + $(document).scrollTop(),true,isclean);
                            // draw(e.clientX - that.can_edit.offset().left, 
                            //         e.clientY - that.can_edit.offset().top + $(document).scrollTop(),true,isclean);
                            
                        }
                        return false;
                    }
                // }
            });

            _that.can_edit.on("touchstart", function (e){
                _.active_img = that
                // 重置range的值
                var scale = resetRange();
                that.showTop();
                if (e.originalEvent.touches.length == 2) {
                    doubleTap = true;
                    SizeCalculate.initDistance(
                        e.originalEvent.touches[0].screenX,
                        e.originalEvent.touches[0].screenY,
                        e.originalEvent.touches[1].screenX,
                        e.originalEvent.touches[1].screenY,
                        scale / 50
                    )
                } else {
                    doubleTap = false;
                }
                e = e.originalEvent.touches[0];
                ox2 = e.screenX
                oy2 = e.screenY
                if (isclean){
                    saveimgdata();
                }
                drawState = true;
                var x = e.clientX - that.can_box.offset().left;
                var y = e.clientY - that.can_box.offset().top + $(document).scrollTop();
                // var x = e.clientX - that.can_edit.offset().left;
                // var y = e.clientY - that.can_edit.offset().top + $(document).scrollTop();
                if (isClip) {
                    that.clipStart(x, y);
                    return false;
                }
                if (canmove === false){
                    saveimgdata();
                    drawState = true;
                    that.lastX = x;
                    that.lastY = y;
                    draw(x, y, false, isclean);
                    return false;
                }
            });
            _that.can_edit.on("touchmove", function (ev){
            	var e;
                e = ev.originalEvent.touches[0];
                if (isClip && clip_start) {
                    that.clipMove(e.clientX - that.can_box.offset().left, 
                                    e.clientY - that.can_box.offset().top + $(document).scrollTop());
                    return false;
                }
                if (doubleTap) {
                    if (ev.originalEvent.touches.length == 2) {
                        SizeCalculate.changeDistance(
                            ev.originalEvent.touches[0].screenX,
                            ev.originalEvent.touches[0].screenY,
                            ev.originalEvent.touches[1].screenX,
                            ev.originalEvent.touches[1].screenY
                        )
                        var scale = SizeCalculate.getScale();
                        // window.document.title = scale
                        // _that.changeBoxScale(scale)
                        return false;
                    } else {
                        doubleTap = false;
                    }
                }
                if (_.active_img == that || true){
                    if (drawState){
                        if (canmove){ 
                            if (_.active_img == that){
                                var nx = that.can_box[0].offsetLeft
                                var ny = that.can_box[0].offsetTop
                                // var nx = that.can_edit.position().left
                                // var nx = that.can_edit[0].offsetLeft
                                // var ny = that.can_edit.position().top
                                // var ny = that.can_edit[0].offsetTop
                                var left = e.screenX - ox2 + nx;
                                var top = e.screenY - oy2 + ny;
                                ox2 = e.screenX;
                                oy2 = e.screenY;
                                that.can_box.css({left:left+"px", top: top + "px"});
                                // that.can_edit.css({left:left+"px", top: top + "px"});
                                // that.can_img.css({left:left+"px", top: top + "px"});
                            }
                        }else{
                            if (_that.lastX == null || _that.lastY == null ){
                                _.active_img.lastX = _.active_img.lastY = null;
                                _that.lastX = e.clientX - that.can_box.offset().left;
                                _that.lastY = e.clientY - that.can_box.offset().top + $(document).scrollTop()
                                // _that.lastX = e.clientX - that.can_edit.offset().left;
                                // _that.lastY = e.clientY - that.can_edit.offset().top + $(document).scrollTop()
                            }
                            draw(e.clientX - that.can_box.offset().left, 
                                e.clientY - that.can_box.offset().top + $(document).scrollTop(),true,isclean);
                            // draw(e.clientX - that.can_edit.offset().left, 
                            //     e.clientY - that.can_edit.offset().top + $(document).scrollTop(),true,isclean);
                            return false;
                        }
                    }
                }
                return false;
            });
            $(document).on("touchend", function (e){
                if (isClip) {
                    that.stopClip();
                    return;
                }
                drawState = false;
                if (doubleTap) {
                    // _that.scale(SizeCalculate.getScale());
                    doubleTap = false;
                }
            });
        };

        var clipAreaNode = {
        	parent: _that,
            area: null,
            clipArea_start_x: 0,
            clipArea_start_y: 0,
            setConfirm: function (indeed, cancel){
                if (window.confirm("确认裁剪？")) {
                    indeed();
                } else {
                    cancel();
                }
            },
            doClip: function (){
                var x = clipAreaNode.clipArea_start_x,
                y = clipAreaNode.clipArea_start_y,
                w = clipAreaNode.area.width(),
                h = clipAreaNode.area.height();
                var tmp_can = $('<canvas width="'+w+'" height="'+h+'">').get(0);
                var tmp_ctx = tmp_can.getContext('2d');
                tmp_ctx.drawImage(_that.can_img.get(0), x, y, w, h, 0, 0, w, h);
                var base64 = tmp_can.toDataURL();
                _that.img.onload = function (){
                    _that._loadimg(this, 2);
                }
                _that.img.src = base64;
                clipAreaNode.area.remove();
                clipAreaNode.area = null;
                isClip = false;
                clip_start = false;
            }
        };
        var clip_start = false;

        // 开始裁剪
        this.clipStart = function (x, y){
            // 创建裁剪区域
            clip_start = true;
            var box = getClipArea();
            clipAreaNode.clipArea_start_x = x;
            clipAreaNode.clipArea_start_y = y;
        }
        
        function getClipArea() {
            if (!clipAreaNode.area) {
                clipAreaNode.area = $('<div class="zcan-clip-area" style="position: relative;border: 1px solid red;z-index: 12;">').appendTo(_that.can_box);
                console.log(clipAreaNode.area)

            }
            return clipAreaNode.area;
        }

        // 选择裁剪区域
        this.clipMove = function (x, y){
            var box = getClipArea();
            box.css(changeClipPosition(x, y, 
                clipAreaNode.clipArea_start_x, 
                clipAreaNode.clipArea_start_y));
        }

        function changeClipPosition(x, y, down_x, down_y) {
            var css = {width: Math.abs(x-down_x), height: Math.abs(y-down_y)}
            // 左上
            if (x < down_x && y < down_y)
            {
                css.left = x,css.top=y;
            }
            else
            // 右上
            if (x > down_x && y < down_y)
            {
                css.left = down_x,css.top=y;
            }
            else
            // 左下
            if (x < down_x && y > down_y)
            {
                css.left = x,css.top=down_y;
            }
            else
            // 右下
            {
                css.left = down_x,css.top=down_y;
            }
            return css;
        } 

        // 停止裁剪
        this.stopClip = function (){
            clip_start = false;
            ;(function (obj){
	            obj.setConfirm(function (){
	                obj.doClip();
	            }, function (){
	                obj.area.remove();
	                obj.area = null;
	            })
            })(clipAreaNode);
        }

        // 画画
        function draw(x, y, isDown, isclean){
            var ctx = _that.ctx_edit;
            if (isDown) {
                ctx.globalCompositeOperation = isclean ? "destination-out" : "source-over";
                ctx.beginPath();
                ctx.strokeStyle = pancolor;
                ctx.lineWidth = isclean ? 30 : pansize;
                ctx.lineJoin = "round";
                ctx.moveTo(_that.lastX, _that.lastY);
                if (_that.lastX == x && _that.lastY == y){
                    x++;
                    y++;
                }
                ctx.lineTo(x, y);
                ctx.closePath();
                ctx.stroke();
            }
            _that.lastX = x;
            _that.lastY = y;
        };
        function cleanRect(x,y,isDown){
            var ctx = _that.ctx_edit;
            if (isDown) {
                ctx.beginPath();
            // ctx.globalCompositeOperation = "destination-out";
                ctx.strokeStyle = 'blue';
                ctx.lineWidth = 30;
                ctx.lineJoin = "round";
                ctx.moveTo(_that.lastX, _that.lastY);
                if (_that.lastX == x && _that.lastY == y){
                    x++;
                    y++;
                }
                ctx.lineTo(x, y);
                ctx.stroke();
            }
        };
        // 保存
        function saveimgdata(){
            if (_that.max_history <= _that.imgdatalist_img.length)
            {
                _that.imgdatalist_img.shift();
                _that.imgdatalist_edit.shift();
            }
            _that.imgdatalist_img.push({rotate: _that.rotatestate,data: _that.ctx_img.getImageData(0,0,_that.width, _that.height)});
            _that.imgdatalist_edit.push({rotate: _that.rotatestate,data: _that.ctx_edit.getImageData(0,0,_that.width, _that.height)});
            utillist.redoBtn.removeClass("disabled");
        };

        /**
         * 两点缩放计算对象
         */
        var SizeCalculate = {
            // 手指的中心点
            center: {x:0,y:0},
            init_distance: 1,
            change_distance: 1,
            scale: 1,
            initDistance: function (x1, y1, x2, y2, scale){
                var x = x1-x2;
                var y = y1-y2;
                this.init_distance = Math.sqrt(x*x+y*y);
                this.scale = scale;
            },
            changeDistance: function (x1, y1, x2, y2) {
                var x = x1-x2;
                var y = y1-y2;
                this.change_distance = Math.sqrt(x*x+y*y);
                // window.document.title= this.change_distance
            },
            getScale: function (){
                window.document.title= this.change_distance + ":" + this.init_distance + ":" + this.change_distance / this.init_distance
                return this.change_distance / this.init_distance * this.scale;
            }
        }

        // 画布中内容旋转,旋转90度
        /*
            不能直接用画布旋转，会影响坐标， 左旋 -- 
        */
        this.rotateLeft = function (){
            if (this.rotatestate == 0){
                this.rotatestate = 3
            }else{
                this.rotatestate-- 
            }
            var obj = this.ctx_img.getImageData(0,0,this.width, this.height);
            var new_obj = this.ctx_img.createImageData(obj.height, obj.width);
            var obj2 = this.ctx_edit.getImageData(0,0,this.width, this.height);
            var new_obj2 = this.ctx_edit.createImageData(obj2.height, obj2.width);
            var num = 0;
            var num2 = 0;
            for (var i=obj.width;i>0;i--){
                for (var j=0;j<obj.height;j++){
                    new_obj.data[num++] = obj.data[((i-1) + j*obj.width)*4]
                    new_obj.data[num++] = obj.data[((i-1) + j*obj.width)*4+1]
                    new_obj.data[num++] = obj.data[((i-1) + j*obj.width)*4+2]
                    new_obj.data[num++] = obj.data[((i-1) + j*obj.width)*4+3]
                    new_obj2.data[num2++] = obj2.data[((i-1) + j*obj2.width)*4]
                    new_obj2.data[num2++] = obj2.data[((i-1) + j*obj2.width)*4+1]
                    new_obj2.data[num2++] = obj2.data[((i-1) + j*obj2.width)*4+2]
                    new_obj2.data[num2++] = obj2.data[((i-1) + j*obj2.width)*4+3]
                }
            }
            this.width = new_obj.width
            this.height = new_obj.height
            // this.showCenter();
            this.can_box.css("left",this.can_box.css("left").split('px')[0]-(this.width-this.height)/2 + 'px')
            this.can_box.css("top",this.can_box.css("top").split('px')[0]-(this.height-this.width)/2 + 'px')
            this.resizeWH(this.width, this.height);
            this.ctx_img.clearRect(0,0,this.width,this.height);  
            this.ctx_img.putImageData(new_obj, 0, 0);
            this.ctx_edit.clearRect(0,0,this.width,this.height);  
            this.ctx_edit.putImageData(new_obj2, 0, 0);
        };
        this.rotateRight = function (){
            if (this.rotatestate == 3){
                this.rotatestate = 0
            }else{
                this.rotatestate++ 
            }
            var obj = this.ctx_img.getImageData(0,0,this.width, this.height);
            var new_obj = this.ctx_img.createImageData(obj.height, obj.width);
            var obj2 = this.ctx_edit.getImageData(0,0,this.width, this.height);
            var new_obj2 = this.ctx_edit.createImageData(obj.height, obj.width);
            var num = 0;
            var num2 = 0;
            for (var j=0;j<obj.width;j++){
                for (var i=obj.height;i>0;i--){
                    new_obj.data[num++] = obj.data[(j + obj.width*(i-1))*4]
                    new_obj.data[num++] = obj.data[(j + obj.width*(i-1))*4+1]
                    new_obj.data[num++] = obj.data[(j + obj.width*(i-1))*4+2]
                    new_obj.data[num++] = obj.data[(j + obj.width*(i-1))*4+3]
                    new_obj2.data[num2++] = obj2.data[(j + obj2.width*(i-1))*4]
                    new_obj2.data[num2++] = obj2.data[(j + obj2.width*(i-1))*4+1]
                    new_obj2.data[num2++] = obj2.data[(j + obj2.width*(i-1))*4+2]
                    new_obj2.data[num2++] = obj2.data[(j + obj2.width*(i-1))*4+3]
                }
            }
            this.width = new_obj.width
            this.height = new_obj.height
            // this.showCenter();
            // 居中显示
            var old_left = this.can_box.css("left")
            var old_top = this.can_box.css("top")
            this.can_box.css("left",this.can_box.css("left").split('px')[0]-(this.width-this.height)/2 + 'px')
            this.can_box.css("top",this.can_box.css("top").split('px')[0]-(this.height-this.width)/2 + 'px')
            this.resizeWH(this.width, this.height);
            this.ctx_img.clearRect(0,0,this.width,this.height);  
            this.ctx_img.putImageData(new_obj, 0, 0);
            this.ctx_edit.clearRect(0,0,this.width,this.height);  
            this.ctx_edit.putImageData(new_obj2, 0, 0);
        };
        this.rotate0 = function (img){
            var obj = img2imageData(img);
            return imageData2base64(obj);
        };
        this.rotate1 = function (img){
            var obj = img2imageData(img);
            var new_obj = this.ctx_img.createImageData(obj.height, obj.width);
            var num = 0;
            for (var j=0;j<obj.width;j++){
                for (var i=obj.height;i>0;i--){
                    new_obj.data[num++] = obj.data[(j + obj.width*(i-1))*4]
                    new_obj.data[num++] = obj.data[(j + obj.width*(i-1))*4+1]
                    new_obj.data[num++] = obj.data[(j + obj.width*(i-1))*4+2]
                    new_obj.data[num++] = obj.data[(j + obj.width*(i-1))*4+3]
                }
            }
            return imageData2base64(new_obj);
        };
        this.rotate2 = function (img){
            var obj = img2imageData(img);
            var new_obj = this.ctx_img.createImageData(obj.width, obj.height);
            var num = 0;
            for (var i=obj.height;i>0;i--){
                for (var j=obj.width;j>0;j--){
                    new_obj.data[num++] = obj.data[((j-1) + ((i-1)*obj.width))*4]
                    new_obj.data[num++] = obj.data[((j-1) + ((i-1)*obj.width))*4+1]
                    new_obj.data[num++] = obj.data[((j-1) + ((i-1)*obj.width))*4+2]
                    new_obj.data[num++] = obj.data[((j-1) + ((i-1)*obj.width))*4+3]
                }
            }
            return imageData2base64(new_obj);
        };
        this.rotate3 = function (img){
            var obj = img2imageData(img);
            var new_obj = this.ctx_img.createImageData(obj.height, obj.width);
            var num = 0;
            for (var i=obj.width;i>0;i--){
                for (var j=0;j<obj.height;j++){
                    new_obj.data[num++] = obj.data[((i-1) + j*obj.width)*4]
                    new_obj.data[num++] = obj.data[((i-1) + j*obj.width)*4+1]
                    new_obj.data[num++] = obj.data[((i-1) + j*obj.width)*4+2]
                    new_obj.data[num++] = obj.data[((i-1) + j*obj.width)*4+3]
                }
            }
            return imageData2base64(new_obj);
        };
        this.resizeWH = function (w, h){
            this.can_box.css("width", w+3);
            this.can_box.css("height",h+3);
            this.can_img.attr("width", w);
            this.can_img.attr("height",h);
            this.can_edit.attr("width", w);
            this.can_edit.attr("height",h);
        }
        function img2imageData(img){
            img = $(img)[0];
            var width = img.naturalWidth;
            var height = img.naturalHeight;
            var can = $("<canvas>").attr("width", width).attr("height", height);
            can = can[0];
            var ctx = can.getContext("2d");
            ctx.drawImage(img, 0, 0, width, height, 0,0, width, height);
            return ctx.getImageData(0,0,width, height);
        }

        function imageData2base64(imgdata){
            var can = $("<canvas>").attr("width", imgdata.width).attr("height", imgdata.height);
            can = can[0];
            var ctx = can.getContext("2d");
            ctx.putImageData(imgdata, 0, 0);
            return can.toDataURL();
        }

        this.scale = function (size){
            // 先产生一个带旋转角度的原生图片
            var that = this;
            // var data = this.can_img[0].toDataURL();
            var data = this["rotate" + this.rotatestate](this.oimg);
            var img = $("<img>").attr("src", data)
            img[0].onload = function (){
                // that._loadimg(img[0], 0, size);
                var data2 = that.can_edit[0].toDataURL();
                var img2 = $("<img>").attr("src", data2)
                // 编辑canvas
                img2[0].onload = function (){
                    var width = img2[0].naturalWidth * size
                    var height = img2[0].naturalHeight * size
                    that._loadimg2(img2[0], img[0], width, height);
                }
            }
        };



        // 初始化状态图片的容器
        function _img_init (obj, data){
            var imghei =( $(window).height() -obj.height)/2/$(window).height()*100+'%';       
            _that.can_img = $("<canvas style='z-index:1;' />").css({"position":"absolute","top":0, "left":0});
            _that.can_edit = $("<canvas style='z-index:2;' />").css({"position":"absolute","top":0, "left":0});
            _that.can_box = $("<div class='clearfix'/>")
                                .css({"position":"absolute","top":imghei, "display": 'inline-block'})
                                .append(_that.can_img).append(_that.can_edit);
            if (data)
            {
                _that.loadData(data);
            }
            if (_._default_option.beforeLoad != null)
            {
                _._default_option.beforeLoad(_, _that, _that.can_box, _that.can_data)
            }
            container.append(_that.can_box)
            _that.ctx_img = _that.can_img[0].getContext("2d");
            _that.ctx_edit = _that.can_edit[0].getContext("2d");
            _that.width = $(document).width();
            _that.height = $(document).height();
            _that.resizeWH(_that.width, _that.height);
            _that._loadimg(obj, 2);
            // 装载画画事件
            registDraw();
        };
        // 销毁
        this._destruct = function (){
            this.can_img.remove();
            this.can_edit.remove();
            this.can_box.remove();
            _that.can_img = _that.can_edit = _that.ctx_img = _that.ctx_edit = null;
        };
        /*
            重置图片的大小
            w 宽
            h 高
            m 模式：1 显示全部，大小自适应，2 填充，大小自适应， 3 拉伸
        */
        this.resizeTo = function (w, h, m){
            var width = this.width;
            var height = this.height;
            var img = $(this.oimg)[0];
            var n_w = img.naturalWidth
            var n_h = img.naturalHeight
            if (m == 3){
                this.width = w;this.height = h;
            }
            else if (m == 2){
                if (width/height > w/h){
                    this.height = h;
                    this.width = h / height * width;
                }else{
                    this.width = w;
                    this.height = w / width * height;
                }
            }else if (m == 1){
                if (width/height < w/h){
                    this.height = h;
                    this.width = h / height * width;
                }else{
                    this.width = w;
                    this.height = w / width * height;
                }
            }   
            this.resizeWH(this.width, this.height);
            this.ctx_img.drawImage(img, 0, 0, n_w, n_h, 0,0, this.width,this.height);
        }

        /*
            重置图片大小
            将放大倍数与党建放大倍数进行对比，
            计算书参数的真正放大倍数
        */ 
        this.changeScale = function(size){
            var new_size = size * (this.oimg.naturalWidth + this.oimg.naturalHeight) / (this.width + this.height);
            this.scale(new_size)
            if ($('#can_shadow_img').length > 0){
                $('#can_shadow_img').remove();
            }
        }

        this.changeBoxScale = function (size){
            var new_size = size * (this.oimg.naturalWidth + this.oimg.naturalHeight) / (this.width + this.height);
            if ($('#can_shadow_img').length <= 0)
            {
                var obj = this.ctx_img.getImageData(0,0,this.width, this.height);
                var base64 = imageData2base64(obj);
                $('<img id="can_shadow_img">').attr('src', base64).css({
                        position: 'absolute',
                        left: 0,
                        top: 0,
                        width: this.width,
                        height: this.height,
                        zIndex: 9
                    }).appendTo(this.can_box)
                this.can_img.css({opacity: 0});
                this.can_edit.css({opacity: 0});
            }
            $('#can_shadow_img').css({
                        width: this.width * new_size,
                        height: this.height * new_size
                    })
            var left = parseFloat(this.can_box.css('left'));
            var top = parseFloat(this.can_box.css('top'));
            var w = parseFloat(this.can_box.css('width'));
            var h = parseFloat(this.can_box.css('height'));
            var center_left = left + w / 2;
            var center_top = top + h / 2;
            var new_w = this.width * new_size;
            var new_h = this.height * new_size;
            this.can_box.css({
                        width: new_w + 3,
                        height: new_h + 3,
                        left: center_left - new_w / 2,
                        top: center_top - new_h / 2,
                    })
        }

        /*
            重置图片的位置
        */
        this.removeTo = function (x, y){
            this.can_box.css({top: y, left: x});
            // this.can_edit.css({top: y, left: x});
            // this.can_img.css({top: y, left: x});
        }
        /*
            保存图片功能，将图片保存成一张图片并返回base64
        */
        this.saveAsBase64 = function (){
            var obj = this.ctx_img.getImageData(0,0,this.width, this.height);
            var obj2 = this.ctx_edit.getImageData(0,0,this.width, this.height);
            var new_obj = this.ctx_img.createImageData(this.width, this.height);
            var len = obj2.data.length / 4;
            for(var i=0;i<len;i++){
                if (obj2.data[i*4+3] != 0){
                    new_obj.data[i*4] = obj2.data[i*4]
                    new_obj.data[i*4+1] = obj2.data[i*4+1]
                    new_obj.data[i*4+2] = obj2.data[i*4+2]
                    new_obj.data[i*4+3] = 255
                }else{
                    new_obj.data[i*4] = obj.data[i*4];
                    new_obj.data[i*4+1] = obj.data[i*4+1];
                    new_obj.data[i*4+2] = obj.data[i*4+2];
                    new_obj.data[i*4+3] = obj.data[i*4+3];
                }
            }
            console.log(imageData2base64(new_obj))
            return imageData2base64(new_obj)
        }
        // 状态事件
        _img_init(img, data);
    }
    
/************************************************/
}))
